package site_announcement

import (
	"context"
	"fmt"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/utils"
	"git.myscrm.cn/golang/stark/v4"
	"gorm.io/gorm"
	"time"
)

type SiteAnnouncementRepository struct {
}

func NewSiteAnnouncementRepository() SiteAnnouncementRepositoryIface {
	return &SiteAnnouncementRepository{}
}

func (r *SiteAnnouncementRepository) SaveSiteAnnouncement(ctx context.Context, po *SiteAnnouncementPo) (*SiteAnnouncementPo, error) {
	// 先查询是否存在，如果存在就更新，不存在就插入
	db := stark.MySQLConn.Get(ctx)
	var data SiteAnnouncementPo
	err := db.Table(po.TableName()).Where("id = ? and is_deleted = ?", po.Id, constants.IsDeletedFalse).First(&data).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}
	data.Title = po.Title
	data.Content = po.Content
	data.Url = po.Url
	data.Cycle = po.Cycle
	data.StartTime = po.StartTime
	data.EndTime = po.EndTime
	data.ModifiedOn = time.Now()
	data.ModifiedBy = po.ModifiedBy
	data.IsDeleted = constants.IsDeletedFalse
	if data.Id == 0 {
		// 新增
		data.CreatedBy = po.CreatedBy
		data.CreatedOn = po.CreatedOn
		err = db.Table(po.TableName()).Create(&data).Error
		if err != nil {
			return nil, err
		}
	} else {
		// 更新
		err = db.Table(po.TableName()).Save(&data).Error
		if err != nil {
			return nil, err
		}
	}
	return &data, nil
}

func (r *SiteAnnouncementRepository) QuerySiteAnnouncementList(ctx context.Context, condition map[string]interface{}, pageInfo *utils.PageInfo, orderBy string) (int64, []*SiteAnnouncementPo, error) {
	var result []*SiteAnnouncementPo
	var count int64
	db := stark.MySQLConn.Get(ctx)
	if val, ok := condition["ids"]; ok {
		db = db.Where("id not in (?)", val)
		delete(condition, "ids")
	}
	if val, ok := condition["current_time"]; ok {
		db = db.Where("start_time < ? AND end_time > ?", val, val)
		delete(condition, "current_time")
	}

	db = db.Table(SiteAnnouncementPo{}.TableName()).Where(condition)
	err := db.Count(&count).Error
	if err != nil {
		return 0, nil, err
	}
	if pageInfo != nil && pageInfo.PageSize > 0 && pageInfo.Page > 0 {
		db = db.Offset((pageInfo.Page - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize)
	}
	if orderBy != "" {
		db = db.Order(orderBy)
	}
	err = db.Find(&result).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return 0, result, nil
		}
		return 0, nil, err
	}
	return count, result, nil
}

func (r *SiteAnnouncementRepository) DeleteSiteAnnouncement(ctx context.Context, id int64, modifiedBy string) error {
	db := stark.MySQLConn.Get(ctx)
	err := db.Table(SiteAnnouncementPo{}.TableName()).
		Where("id = ? and is_deleted = ?", id, constants.IsDeletedFalse).
		Updates(map[string]interface{}{
			"is_deleted":  constants.IsDeletedTrue,
			"modified_on": time.Now(),
			"modified_by": modifiedBy,
		}).Error
	if err != nil {
		return err
	}

	return nil
}

func (r *SiteAnnouncementRepository) GetSiteAnnouncementDetail(ctx context.Context, id int64) (*SiteAnnouncementPo, error) {
	db := stark.MySQLConn.Get(ctx)
	var data SiteAnnouncementPo
	err := db.Table(SiteAnnouncementPo{}.TableName()).Where("id = ? and is_deleted = ?", id, constants.IsDeletedFalse).First(&data).Error
	if err != nil {
		return nil, err
	}
	return &data, nil
}

func (r *SiteAnnouncementRepository) IsRepeatTitle(ctx context.Context, title string, id int64) (bool, error) {
	db := stark.MySQLConn.Get(ctx)
	db = db.Table(SiteAnnouncementPo{}.TableName()).
		Where("title = ? and is_deleted = ?", title, constants.IsDeletedFalse)
	if id > 0 {
		db = db.Where("id <> ?", id)
	}
	err := db.First(&SiteAnnouncementPo{}).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		stark.Logger.Errorf(ctx, "IsRepeatTitle error: %v", err)
		return true, err
	} else if err == gorm.ErrRecordNotFound {
		return false, nil
	} else {
		return true, nil
	}
}

func (r *SiteAnnouncementRepository) SetSiteAnnouncementViewRecord(ctx context.Context, siteAnnouncementId, userId int64, tenantCode string) (int64, error) {
	// 先查询是否存在，如果存在就更新，不存在就插入
	db := stark.MySQLConn.Get(ctx)
	var data SiteAnnouncementViewRecord
	err := db.Table(SiteAnnouncementViewRecord{}.TableName()).
		Where("site_announcement_id = ? and user_id = ? and tenant_code = ? and is_deleted = ? ",
			siteAnnouncementId, userId, tenantCode, constants.IsDeletedFalse).First(&data).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return 0, err
	}
	data.SiteAnnouncementID = siteAnnouncementId
	data.TenantCode = tenantCode
	data.UserID = userId
	data.Status = constants.ReadStatus
	data.ViewTime = time.Now()
	data.ModifiedOn = time.Now()
	data.ModifiedBy = fmt.Sprintf("%d", userId)
	data.IsDeleted = constants.IsDeletedFalse
	if data.Id == 0 {
		// 新增
		data.CreatedBy = fmt.Sprintf("%d", userId)
		data.CreatedOn = time.Now()
		err = db.Table(data.TableName()).Create(&data).Error
		if err != nil {
			return 0, err
		}
	} else {
		// 更新
		err = db.Table(data.TableName()).Save(&data).Error
		if err != nil {
			return 0, err
		}
	}
	return data.Id, nil
}

func (r *SiteAnnouncementRepository) GetUserViewRecord(ctx context.Context, userId int64, tenantCode string) ([]int64, error) {
	var ids []int64
	db := stark.MySQLConn.Get(ctx)
	err := db.Table(SiteAnnouncementViewRecord{}.TableName()+" r").
		Joins("LEFT JOIN site_announcement s on s.id = r.site_announcement_id").
		Where("s.cycle = ? and r.`status` = ? and r.user_id = ? and r.tenant_code = ? and s.is_deleted = ? and r.is_deleted = ?", constants.FirstCycle, constants.ReadStatus, userId, tenantCode, constants.IsDeletedFalse, constants.IsDeletedFalse).
		Pluck("s.id", &ids).Error
	if err != nil {
		return nil, err
	}

	return ids, nil
}
